package com.yx.frame.builder.code;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Text;
import com.yx.frame.builder.xml.ServiceBuilderXml;
import com.yx.frame.service.Action;

public class CodeGenerator {
	File rootPath;
	List<Action> actions = new ArrayList<Action>();
	private Text message;
	ProgressBar progressBar;
	int fileNumber = 0;
	int processFileNumber = 0;
	StringBuffer messageStr = new StringBuffer();
	String jsFileName;
	String jsControlName;
	boolean isJDK18=true;
	boolean isJety=true;
	long timeDifference=-1;

	public CodeGenerator(String rPath, String jsFileName, String jsControlName, Text message, ProgressBar progressBar,boolean isJDK18,boolean isJety,long timeDifference) {
		this.rootPath = new File(rPath);
		this.message = message;
		this.progressBar = progressBar;
		this.jsFileName = jsFileName;
		this.jsControlName = jsControlName;
		this.isJDK18=isJDK18;
		this.isJety=isJety;
		this.timeDifference=timeDifference;
		addMessage("开始检索需要编译的文件.....");
		calculateFileNumber(rootPath);
		addMessage("OK!\r\n");
		progressBar.setMinimum(0);
		progressBar.setMaximum(fileNumber);
		addMessage("开始编译文件,文件总数量为" + fileNumber + "个.....\r\n");
		try {
			JsFileWriter jsWriter = ClassBuilder.createJsWebFile(rootPath.getPath(), jsFileName, jsControlName);
			JavaClientCode javaClient = new JavaClientCode(rootPath.getPath(), jsFileName, jsControlName);
			IosClientCode iosClient = new IosClientCode(rootPath.getPath(), jsFileName, jsControlName);
			javaClient.writeHead();
			iosClient.writePublic();
			searchDirectory(rootPath, jsWriter, javaClient,iosClient);
			jsWriter.write("true", "};\r\n");
			jsWriter.write("true", "var " + jsControlName + "=new " + jsFileName + "();\r\n");
			jsWriter.flush();
			jsWriter.close();
			javaClient.close();
			iosClient.close();
			addMessage("开始创建Action并生成启动文件.....");
			analyzeActions();
			addMessage("OK!\r\n");
			addMessage("系统编译完毕！\r\n");
		} catch (Exception e) {

		}
	}

	public void addMessage(String msg) {
		messageStr.append(msg);
		message.setText(messageStr.toString());
	}

	private void calculateFileNumber(File file) {
		if (file.isDirectory()) {
			File[] files = file.listFiles(new xmlFilter());
			for (int i = 0; i < files.length; i++) {
				File f = files[i];
				calculateFileNumber(f);
			}
		} else if (file.getName().endsWith(".rsb")) {
			fileNumber++;
		}
	}

	private void searchDirectory(File file, JsFileWriter writer, JavaClientCode javaClient,IosClientCode iosClient) {
		if (file.isDirectory()) {
			File[] files = file.listFiles(new xmlFilter());
			for (int i = 0; i < files.length; i++) {
				File f = files[i];
				searchDirectory(f, writer, javaClient,iosClient);
			}
		} else if (file.getName().endsWith(".rsb")) {
			analyzeRsbFile(file, writer, javaClient,iosClient);
		}
	}

	private void analyzeActions() {
		Action tmpAction;
		for (int i = 1; i < actions.size(); i++) {
			for (int j = i; (j > 0) && (actions.get(j).getId() < actions.get(j - 1).getId()); j--) {
				tmpAction = actions.get(j);
				actions.set(j, actions.get(j - 1));
				actions.set(j - 1, tmpAction);
			}
		}
		boolean isEorror = false;
		for (int i = 0; i < actions.size() - 1; i++) {

			Action action = actions.get(i);
			if (i == 0) {
				for (int j = 0; j < action.getId(); j++) {
					Action emptyAction = new Action(j, "empty", "empty", "empty", "空操作，没有定义");
					actions.add(j, emptyAction);
					i = j + 1;
				}
			}
			Action nextAction = actions.get(i + 1);
			if (action.getId() == nextAction.getId()) {
				isEorror = true;
				System.out.println(action.getService() + "/" + action.getMethod() + "与" + nextAction.getService() + "/"
						+ nextAction.getMethod() + "的ID重复，请务必修改！");
			} else {
				for (int j = action.getId() + 1; j < nextAction.getId(); j++) {
					Action emptyAction = new Action(j, "empty", "empty", "empty", "空操作，没有定义");
					actions.add(j, emptyAction);
				}
			}
		}
		if (actions.size() == 1) {// 用于如果只有一条并且ID>0的情况
			Action action = actions.get(0);
			for (int i = 0; i < action.getId(); i++) {
				Action emptyAction = new Action(i, "empty", "empty", "empty", "空操作，没有定义");
				actions.add(i, emptyAction);
			}
		}
		if (isEorror) {
			return;
		}
		File path = new File(rootPath.getPath() + "/builder/");
		if (!path.exists()) {
			path.mkdirs();
		}
		File file = new File(rootPath.getPath() + "/builder/Starter.java");
		if (file.exists()) {
			file.delete();
		}
		try {
			OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
			ActionCodeBuilder actionCodeBuilder = new ActionCodeBuilder(actions, writer, isJDK18, isJety,timeDifference);
			actionCodeBuilder.builder();
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		File controllerFile = new File(rootPath.getPath() + "/builder/LocalController.java");
		if (!controllerFile.exists()) {
			try {
				OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(controllerFile), "UTF-8");
				writer.write("package builder;\r\n");
				writer.write("import com.yx.frame.authority.User;\r\n");
				writer.write("import com.yx.frame.server.BasicProvider;\r\n");
				writer.write("public class LocalController extends BasicProvider {\r\n");
				writer.write("	public LocalController() {\r\n");						
				writer.write("	}\r\n");
				writer.write("	@Override\r\n");
				writer.write("	public User loadUser(String arg0) throws Exception {\r\n");
				writer.write("		// TODO Auto-generated method stub\r\n");
				writer.write("		return null;\r\n");
				writer.write("	}\r\n");
				writer.write("}\r\n");
				writer.flush();
				writer.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if(!isJety){
			File web_inf = new File(rootPath.getPath() + "/builder/WEB-INF");
			if(!web_inf.exists())web_inf.mkdir();
			File web_xml = new File(rootPath.getPath() + "/builder/WEB-INF/web.xml");
			if(web_xml.exists())web_xml.delete();
			String jdk16="Jre6";
			if(isJDK18)jdk16="";
			try {
				OutputStreamWriter webXmlWriter = new OutputStreamWriter(new FileOutputStream(web_xml), "UTF-8");
				webXmlWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
				webXmlWriter.write("<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n");
				webXmlWriter.write("	version=\"2.5\"\r\n");
				webXmlWriter.write("	xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd\">\r\n");
				webXmlWriter.write("	<servlet>\r\n");
				webXmlWriter.write("		<servlet-name>JsonRemote</servlet-name>\r\n");
				webXmlWriter.write("		<servlet-class>com.yx.frame.http.HttpJsonRemoteServlet"+jdk16+"</servlet-class>\r\n");
				webXmlWriter.write("		<load-on-startup>1</load-on-startup>\r\n");
				webXmlWriter.write("	</servlet>\r\n");
				webXmlWriter.write("	<servlet-mapping>\r\n");
				webXmlWriter.write("		<servlet-name>JsonRemote</servlet-name>\r\n");
				webXmlWriter.write("		<url-pattern>/JsonRemote</url-pattern>\r\n");
				webXmlWriter.write("	</servlet-mapping>\r\n");
				webXmlWriter.write("	<servlet>\r\n");
				webXmlWriter.write("		<servlet-name>FileUpload</servlet-name>\r\n");
				webXmlWriter.write("		<servlet-class>com.yx.frame.http.HttpFileUploadServlet"+jdk16+"</servlet-class>\r\n");
				webXmlWriter.write("		<load-on-startup>2</load-on-startup>\r\n");
				webXmlWriter.write("	</servlet>\r\n");
				webXmlWriter.write("	<servlet-mapping>\r\n");
				webXmlWriter.write("		<servlet-name>FileUpload</servlet-name>\r\n");
				webXmlWriter.write("		<url-pattern>/FileUpload</url-pattern>\r\n");
				webXmlWriter.write("	</servlet-mapping>\r\n");
				webXmlWriter.write("	<servlet>\r\n");
				webXmlWriter.write("		<servlet-name>Download</servlet-name>\r\n");
				webXmlWriter.write("		<servlet-class>com.yx.frame.http.HttpFileDownloadServlet"+jdk16+"</servlet-class>\r\n");
				webXmlWriter.write("		<load-on-startup>3</load-on-startup>\r\n");
				webXmlWriter.write("	</servlet>\r\n");
				webXmlWriter.write("	<servlet-mapping>\r\n");
				webXmlWriter.write("		<servlet-name>Download</servlet-name>\r\n");
				webXmlWriter.write("		<url-pattern>/Download</url-pattern>\r\n");
				webXmlWriter.write("	</servlet-mapping>	\r\n");
				webXmlWriter.write("</web-app>\r\n");
				webXmlWriter.flush();
				webXmlWriter.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			try{
				File web_xml = new File(rootPath.getPath() + "/builder/WEB-INF/web.xml");
				if(web_xml.exists())web_xml.delete();
				File web_inf = new File(rootPath.getPath() + "/builder/WEB-INF");
				if(web_inf.exists())web_inf.delete();
			}catch(Exception e){}
		}

	}

	public void analyzeRsbFile(File file, JsFileWriter writer, JavaClientCode javaClient,IosClientCode iosClient) {
		try {
			ServiceBuilderXml appHelperXml = new ServiceBuilderXml(file);
			if (appHelperXml.isServiceBuilder()) {
				ClassBuilder cBuilder = new ClassBuilder(rootPath, file, appHelperXml, this);
				cBuilder.analyzeToJava(this);
				// cBuilder.analyzeToJsApp(this);
				cBuilder.analyzeToJsWeb(this, writer, this.jsControlName);
				// cBuilder.analyzeTotHttpSampleCode(this);
				cBuilder.analyzeToJavaClient(this, javaClient);
				cBuilder.analyzeToIosClient(this, iosClient,this.jsControlName);
				actions.addAll(cBuilder.getActionDefinations());
				progressBar.setSelection(++processFileNumber);
				addMessage("Rsb文件:" + file.getName() + ".....OK!" + "\r\n");
			}
		} catch (Exception e) {
			e.printStackTrace();
			addMessage("Rsb文件:" + file.getName() + "解析失败：" + e.getMessage() + "\r\n");
			return;
		}
	}

	class xmlFilter implements FileFilter {
		public xmlFilter() {

		}

		public boolean accept(File file) {
			// System.out.println("name:"+file.getName());
			if (file.isDirectory()) {
				return true;
			}
			if (file.getName().endsWith(".java")) {
				return false;
			}
			if (file.getName().endsWith(".rsb") || file.getName().endsWith(".RSB")) {
				return true;
			}
			return false;
		}
	}

}
